﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Reflection;

namespace TestCSImport
{
    class TestHelper : IComparer
    {
        public int Compare(object firstObject, object secondObject)
        {
            bool ret = CompareObjectAttributes(firstObject, secondObject);

            return ret == true ? 0 : -1;
        }

        /* This method takes as input two objects and compares the properties of them.
       It returns true if all the public properties of the objects (not inherited ones) are equal.
         src: http://manfred-ramoser.blogspot.com/2007/11/c-unit-testing-helper.html */
        public static bool CompareObjectAttributes(object firstObject, object secondObject)
        {
            Type t1 = firstObject.GetType();
            Type t2 = secondObject.GetType();
            /*the two objects must have the same type*/
            if (!t1.Equals(t2)) return false;

            PropertyInfo[] infos1 =
                t1.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            PropertyInfo[] infos2 =
                t2.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            for (int i = 0; i < infos1.Length; i++)
            {
                Object value1 = infos1[i].GetValue(firstObject, null);
                Object value2 = infos2[i].GetValue(secondObject, null);

                //both props are null, equal
                if (value2 == null && value1 == null)
                {
                    continue;
                }

                /*this if is needed because if it is a datetime it should compare only the date and the time and not the ticks*/
                if (infos1[i].PropertyType.Equals(typeof(DateTime)))
                {
                    DateTime firstDate = (DateTime)value1;
                    DateTime secondDate = (DateTime)value2;
                    /*if the datatype in the database was date then only compare the date part of the datetime object*/
                    if (firstDate.ToString().Contains("00:00:00") || secondDate.ToString().Contains("00:00:00"))
                    {
                        if (!firstDate.Date.ToString().Equals(secondDate.Date.ToString())) {
                            LogUnequalProperty(infos1[i], value1, infos2[i], value2);
                            return false;
                        };
                    }
                    /*otherwise compare the string representation of the two datetime objects because the ticks may differ*/
                    else
                    {
                        if (!firstDate.ToString().Equals(secondDate.ToString())) {
                            LogUnequalProperty(infos1[i], value1, infos2[i], value2);
                            return false;
                        }
                    }
                }
                else
                {
                    /*if one property value differs return false*/
                    // if one property is null, the other must be also
                    
                    if (value1 == null && value2 != null)
                    {
                        LogUnequalProperty(infos1[i], value1, infos2[i], value2);
                        return false;
                    }
                    if (value2 == null && value1 != null)
                    {
                        LogUnequalProperty(infos1[i], value1, infos2[i], value2);
                        return false;
                    }
                    if (!(value1).Equals(value2))
                    {
                        LogUnequalProperty(infos1[i], value1, infos2[i], value2);
                        return false;
                    }
                }
            }

            /*when everything went fine the objects have the same values for their properties*/
            return true;
        }

        public static void LogUnequalProperty(PropertyInfo p1, Object v1, PropertyInfo p2, Object v2)
        {
            Console.WriteLine("Property: " + p1.Name + " Value: " + v1
                            + " != " + "Property: " + p2.Name + " Value: " + v2);
        }
    }
}
